﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Kimd.Communication
{
    public class DataAnaysisHelper
    {
        /// <summary>
        /// 16进制字符串转换成字节数组
        /// </summary>
        /// <param name="hexStr"></param>
        public byte[] HexStrToByte(string hexStr)
        {
            byte[] returnByte = null;
            try
            {
                hexStr = hexStr.Trim().Replace(" ", "");
                if (hexStr.Length % 2 != 0)
                    hexStr += " ";
                returnByte = new byte[hexStr.Length / 2];
                for (int i = 0; i < returnByte.Length; i++)
                    returnByte[i] = Convert.ToByte(hexStr.Substring(i * 2, 2), 16);
            }
            catch (Exception ex)
            {

            }
            return returnByte;
        }

        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="intervalStr">字符串间隔号</param>
        /// <returns></returns>
        public string ByteToHexStr(byte[] bytes, string intervalStr = "")
        {
            StringBuilder returnStr = new StringBuilder();
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr.Append(bytes[i].ToString("X2") + intervalStr);
                }
            }
            return returnStr.ToString();
        }

        public string ByteToHexStr(byte[] InBytes, char segment)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte InByte in InBytes)
            {
                if (segment == 0) sb.Append(string.Format("{0:X2}", InByte));
                else sb.Append(string.Format("{0:X2}{1}", InByte, segment));
            }

            if (segment != 0 && sb.Length > 1 && sb[sb.Length - 1] == segment)
            {
                sb.Remove(sb.Length - 1, 1);
            }
            return sb.ToString();
        }

        /// <summary>
        /// 16进制字符串转浮点数
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        public float HexStrToFloat(string hexStr)
        {
            string strFloat = hexStr.Replace(" ", "");
            float value = 0;
            uint num = uint.Parse(strFloat, System.Globalization.NumberStyles.AllowHexSpecifier);
            byte[] floatVals = BitConverter.GetBytes(num);
            value = BitConverter.ToSingle(floatVals, 0);
            return value;
        }

        /// <summary>
        ///  16进制字符串转整数
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        public int HexStrToInt(string hexStr)
        {
            int num = Int32.Parse(hexStr, NumberStyles.HexNumber);
            return num;
        }

        /// <summary>
        /// 字符串转16进制字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string StrToHexStr(string str, Encoding encoding)
        {
            byte[] b = encoding.GetBytes(str);//按照指定编码将string编程字节数组
            List<string> result = new List<string>();
            for (int i = 0; i < b.Length; i++)//逐字节变为16进制字符
            {
                result.Add(Convert.ToString(b[i], 16).PadLeft(2, '0'));
            }
            return string.Join(" ", result).ToUpper();
        }

        /// <summary>
        /// 16进制字符串转字符串
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        public string HexStrToStr(string hexStr, Encoding encoding)
        {
            if (string.IsNullOrEmpty(hexStr))
                return string.Empty;
            byte[] vBytes = new byte[] { };
            hexStr = hexStr.Replace(" ", "");
            if (hexStr.Length <= 0) return "";
            if (hexStr.Length % 2 == 1)
            {
                vBytes = new byte[hexStr.Length / 2 + 1];
                hexStr = hexStr.Substring(0, hexStr.Length - 1) + hexStr.Substring(hexStr.Length - 1, 1).PadLeft(2, '0');
            }
            else
            {
                vBytes = new byte[hexStr.Length / 2];
            }
            for (int i = 0; i < hexStr.Length; i += 2)
                if (!byte.TryParse(hexStr.Substring(i, 2), NumberStyles.HexNumber, null, out vBytes[i / 2]))
                    vBytes[i / 2] = 0;
            return encoding.GetString(vBytes);
        }

        /// <summary>
        /// CRC校验
        /// </summary>
        /// <param name="sendStr"></param>
        /// <returns></returns>
        public string GetCRC(byte[] data)
        {
            byte[] Str = data;
            int result = Str[0];
            for (int i = 1; i < Str.Length; i++)
            {
                result ^= Str[i];
            }
            return result.ToString("X");
        }

        /// <summary>
        /// CRC modbus校验 返回16进制字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns>16进制字符串</returns>
        public string GetCRC16_C(byte[] data)
        {
            byte num = 0xff;
            byte num2 = 0xff;
            byte num3 = 1;
            byte num4 = 160;
            byte[] buffer = data;
            for (int i = 0; i < buffer.Length; i++)
            {
                //位异或运算
                num = (byte)(num ^ buffer[i]);
                for (int j = 0; j <= 7; j++)
                {
                    byte num5 = num2;
                    byte num6 = num;
                    //位右移运算
                    num2 = (byte)(num2 >> 1);
                    num = (byte)(num >> 1);
                    //位与运算
                    if ((num5 & 1) == 1)
                    {
                        //位或运算
                        num = (byte)(num | 0x80);
                    }
                    if ((num6 & 1) == 1)
                    {
                        num2 = (byte)(num2 ^ num4);
                        num = (byte)(num ^ num3);
                    }
                }
            }
            return ByteToHexStr(new byte[] { num, num2 });
        }

        /// <summary>
        /// 获取16进制字符串CRC16转换后的16进制字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string CRC16_Check(string HexStr)
        {
            byte[] bytes = HexStrToByte(HexStr);
            string crcStr = GetCRC16_C(bytes);
            string content = HexStr + crcStr;
            return content;
        }

        /// <summary>
        /// 字节数组CRC16转换后的16进制字符串
        /// </summary>
        /// <param name="HexStr"></param>
        /// <returns></returns>
        public string CRC16_Check(byte[] data)
        {
            byte[] bytes = data;
            string crcStr = GetCRC16_C(bytes);
            string content = ByteToHexStr(data) + crcStr;
            return content;
        }
        public string CRC_Check(byte[] data)
        {
            byte[] bytes = data;
            string crcStr = GetCRC(bytes);
            string content = ByteToHexStr(data) + crcStr;
            return content;
        }

        /// <summary>
        /// ascii字符串转字节数组
        /// </summary>
        /// <param name="ASCIIStr"></param>
        /// <returns></returns>
        public byte[] AsciiStrToByte(string asciiStr)
        {
            byte[] returnByte = null;
            returnByte = ASCIIEncoding.Default.GetBytes(asciiStr);
            return returnByte;
        }

        /// <summary>
        /// 字符串转字符数组
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public byte[] StrToByte(string str, Encoding encoding)
        {
            return encoding.GetBytes(str);
        }


        /// <summary>
        /// 字符串 和校验后字符串
        /// </summary>
        /// <param name="index">0-取和校验位低位  1-取和校验位高低位</param>
        /// <param name="str"></param>
        /// <returns></returns>
        public string Sum_Check(int index, string hexStr)
        {
            string str = hexStr.Replace(" ", "");
            string result = str;
            string tmp = Sum(str).ToString("X2");
            if (index == 0)
                result = str + tmp.Substring(tmp.Length - 2, 2);
            else if (index == 1)
            {
                if (tmp.Length == 1)
                    tmp = "000" + tmp;
                else if (tmp.Length == 2)
                {
                    tmp = "00" + tmp;
                }
                else if (tmp.Length == 3)
                {
                    tmp = "0" + tmp;
                }
                string sHighValue = tmp.Substring(0, 2);
                string sLowValue = tmp.Substring(2, 2);
                result = str + sLowValue + sHighValue;
            }
            return result;
        }



        /// <summary>
        /// 字符串和校验
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        public int Sum(string hexStr)
        {
            int byteLength = hexStr.Length / 2;
            string[] bytes = new string[byteLength];
            string strHex;
            int nSum = 0;
            int j = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                strHex = new String(new Char[] { hexStr[j], hexStr[j + 1] });
                bytes[i] = strHex;
                j = j + 2;
            }

            for (int i = 0; i < bytes.Length; i++)
            {
                int b = Int32.Parse(bytes[i].ToString(), System.Globalization.NumberStyles.HexNumber);
                nSum += b;
            }
            return nSum;
        }






        /// <summary>
        /// Ascii字符串转十六进制值字符串
        /// </summary>
        /// <param name="asciiStr"></param>
        /// <returns></returns>
        public string AsciiStrToHexStr(string asciiStr)
        {
            StringBuilder sb = new StringBuilder();
            foreach (char c in asciiStr)
            {
                int tmp = c;
                sb.Append(String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString())));
            }
            return sb.ToString();
        }

        //public static T GetValueFromJObject<T>(JObject json, string propertyName, T default_value)
        //{
        //    if (json.Property(propertyName) != null)
        //        return json.Property(propertyName).Value.Value<T>();
        //    else
        //        return default_value;
        //}

    }
}
